import * as THREE from 'three';
import { BlockType } from './types';
import { getBlock } from './BlockRegistry';
import { TextureManager } from './TextureManager';

export class BlockMesh {
  private static blockGeometry: THREE.BoxGeometry;
  private static textureManager: TextureManager;

  public static init(): void {
    this.blockGeometry = new THREE.BoxGeometry(1, 1, 1);
    this.textureManager = TextureManager.getInstance();
  }

  public static createBlockMesh(blockType: BlockType, position: THREE.Vector3): THREE.Mesh | null {
    if (blockType === BlockType.AIR) return null;

    const block = getBlock(blockType);
    const materials = this.textureManager.createBlockMaterials(block.textures);
    
    const mesh = new THREE.Mesh(this.blockGeometry, materials);
    mesh.position.copy(position);
    mesh.castShadow = true;
    mesh.receiveShadow = true;
    
    return mesh;
  }

  public static createInstancedBlockMesh(blockType: BlockType, positions: THREE.Vector3[]): THREE.InstancedMesh | null {
    if (blockType === BlockType.AIR || positions.length === 0) return null;

    const block = getBlock(blockType);
    const materials = this.textureManager.createBlockMaterials(block.textures);
    
    const instancedMesh = new THREE.InstancedMesh(
      this.blockGeometry,
      materials,
      positions.length
    );

    const matrix = new THREE.Matrix4();
    positions.forEach((position, index) => {
      matrix.setPosition(position);
      instancedMesh.setMatrixAt(index, matrix);
    });

    instancedMesh.instanceMatrix.needsUpdate = true;
    instancedMesh.castShadow = true;
    instancedMesh.receiveShadow = true;

    return instancedMesh;
  }

  public static createTransparentInstancedBlockMesh(blockType: BlockType, positions: THREE.Vector3[]): THREE.InstancedMesh | null {
    if (blockType === BlockType.AIR || positions.length === 0) return null;

    const block = getBlock(blockType);
    const materials = this.textureManager.createTransparentBlockMaterials(block.textures);
    
    const instancedMesh = new THREE.InstancedMesh(
      this.blockGeometry,
      materials,
      positions.length
    );

    const matrix = new THREE.Matrix4();
    positions.forEach((position, index) => {
      matrix.setPosition(position);
      instancedMesh.setMatrixAt(index, matrix);
    });

    instancedMesh.instanceMatrix.needsUpdate = true;
    instancedMesh.castShadow = true;
    instancedMesh.receiveShadow = true;
    
    // 透明方块的特殊设置
    instancedMesh.renderOrder = 1; // 确保在不透明物体之后渲染
    
    return instancedMesh;
  }
}